19. Context Isolation и обмен данными между процессами в Electron
Что такое contextIsolation?
Context Isolation (изоляция контекста) — это функция безопасности в Electron, которая изолирует код предзагрузки (preload) и код рендерера (renderer) от глобального контекста. Это предотвращает возможность внедрения вредоносного кода через уязвимости в веб-приложении.
Когда contextIsolation
включена (по умолчанию в Electron 12 и выше), код рендерера и код предзагрузки выполняются в разных контекстах, что делает невозможным прямой доступ к Node.js API из рендерера. Вместо этого для взаимодействия между процессами используется Inter-Process Communication (IPC).
Настройка contextIsolation
Шаг 1: Включение contextIsolation
По умолчанию contextIsolation
включена в Electron 12 и выше. Однако, если вы используете более старую версию или хотите явно включить/выключить эту функцию, вы можете настроить её в webPreferences
при создании окна.
Пример настройки contextIsolation
в index.js
:
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // Файл предзагрузки
contextIsolation: true, // Включение изоляции контекста
nodeIntegration: false, // Отключение интеграции Node.js в рендерере
},
});
mainWindow.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
});
Шаг 2: Создание файла предзагрузки (preload.js
)
Файл предзагрузки (preload.js
) используется для настройки безопасного взаимодействия между основным процессом и рендерером. В этом файле вы можете предоставить рендереру доступ к определённым API или функциям, используя Inter-Process Communication (IPC).
Пример содержимого preload.js
:
const { contextBridge, ipcRenderer } = require('electron');
// Предоставляем рендереру безопасный доступ к IPC
contextBridge.exposeInMainWorld('YourApp', {
sendMessage: (message) => ipcRenderer.invoke('message-to-main', message),
onMessage: (callback) => ipcRenderer.invoke('message-to-renderer', callback),
});
Обмен данными между основным процессом и рендерером
Шаг 1: Отправка данных из рендерера в основной процесс
Для отправки данных из рендерера в основной процесс используется метод ipcRenderer.send
. В файле предзагрузки мы предоставили рендереру доступ к этому методу через contextBridge
.
Пример отправки данных из рендерера:
// В рендерере (renderer.js)
window.YourApp.sendMessage('Привет из рендерера!');
Обработка данных в основном процессе:
// В основном процессе (index.js)
const { ipcMain } = require('electron');
ipcMain.handle('message-to-main', (event, message) => {
console.log('Получено сообщение из рендерера:', message);
return "Получено";
});
Шаг 2: Отправка данных из основного процесса в рендерер
Для отправки данных из основного процесса в рендерер используется метод ipcRenderer.on
, который мы также предоставили рендереру через contextBridge
.
Пример отправки данных из основного процесса:
// В основном процессе (index.js)
const { BrowserWindow } = require('electron');
const mainWindow = BrowserWindow.getFocusedWindow();
mainWindow.webContents.send('message-to-renderer', 'Привет из основного процесса!');
Обработка данных в рендерере:
// В рендерере (renderer.js)
window.electronAPI.onMessage((event, message) => {
console.log('Получено сообщение из основного процесса:', message);
});
Практическое задание
-
Создайте простое Electron-приложение:
- Создайте окно с включённой
contextIsolation
и отключённойnodeIntegration
. - Добавьте файл предзагрузки (
preload.js
), который предоставляет рендереру доступ к IPC.
- Создайте окно с включённой
-
Реализуйте обмен данными:
- Добавьте кнопку в интерфейсе приложения, которая отправляет сообщение в основной процесс.
- В основном процессе выведите полученное сообщение в консоль.
- Отправьте ответ из основного процесса в рендерер и отобразите его в интерфейсе.
-
Добавьте обработку ошибок:
- Убедитесь, что приложение корректно обрабатывает случаи, когда сообщения не доходят или содержат неверные данные.
Дополнительные задания:
- Реализуйте двусторонний обмен данными между процессами, например, отправку данных из рендерера, их обработку в основном процессе и возврат результата в рендерер.
- Добавьте возможность отправки файлов из рендерера в основной процесс и их обработки.
Заключение
contextIsolation
— это важная функция безопасности в Electron, которая предотвращает уязвимости, связанные с доступом к Node.js API из рендерера. Использование contextBridge
и IPC позволяет безопасно обмениваться данными между основным процессом и рендерером. В этом занятии мы рассмотрели, как настроить contextIsolation
и реализовать обмен данными между процессами.